using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace CodeUtils
{
    public static class EncryptionUtils
    {
        public static byte[] GenerateKey()
        {
            RijndaelManaged provider = new RijndaelManaged();
            provider.GenerateKey();

            return provider.Key;
        }

        public static byte[] GenerateIV()
        {
            RijndaelManaged provider = new RijndaelManaged();
            provider.GenerateIV();

            return provider.IV;
        }

        public static string Decrypt(byte[] encryptedBytes, byte[] key, byte[] iv)
        {
            RijndaelManaged provider = new RijndaelManaged();

            MemoryStream ms = new MemoryStream();

            using (CryptoStream cryptoStream = new CryptoStream(ms, provider.CreateDecryptor(key, iv), CryptoStreamMode.Write))
            {
                cryptoStream.Write(encryptedBytes, 0, encryptedBytes.Length);
            }

            return Encoding.UTF8.GetString(ms.ToArray());
        }

        public static byte[] Encrypt(string value, byte[] key, byte[] iv)
        {
            RijndaelManaged provider = new RijndaelManaged();
            byte[] valueBytes = Encoding.UTF8.GetBytes(value);

            MemoryStream ms = new MemoryStream();

            using (CryptoStream cryptoStream = new CryptoStream(ms, provider.CreateEncryptor(key, iv), CryptoStreamMode.Write))
            {
                cryptoStream.Write(valueBytes, 0, valueBytes.Length);
            }

            return ms.ToArray();
        }

    }
    public class Encryption
    {
        #region Class Constructor

        public Encryption()
        {

        }

        #endregion
        #region Class Static Methods
        /// <summary>
        /// This Function is used to Generate Key      
        /// </summary>
        /// <returns>Byte Array type that hold the Key</returns>
        private static byte[] GenerateKey()
        {
            //TripleDESCryptoServiceProvider tDes = new TripleDESCryptoServiceProvider();
            //tDes.GenerateKey();
            //_DecryptionKey = tDes.Key;
            return new byte[] { 137, 241, 181, 79, 71, 224, 162, 36, 42, 198, 36, 4, 89, 100, 242, 89, 49, 180, 203, 213, 76, 230, 95, 37 };
        }
        /// <summary>
        /// This Function is used to Encrypt the password        
        /// </summary>
        /// <param name="strPassword">String Type Parameter that hold the password in Plain Text</param>
        /// <returns>String Type Parameter that hold the password in Encrypted Form</returns>
        public static string EncryptPassword(string strPassword)
        {
            byte[] _DecryptionKey = GenerateKey();

            System.Text.UnicodeEncoding ue = new System.Text.UnicodeEncoding();
            byte[] uePassword = ue.GetBytes(strPassword);
            byte[] RetVal = null;

            // TripleDes Encrypt format
            TripleDESCryptoServiceProvider tripleDes = new TripleDESCryptoServiceProvider();

            tripleDes.Key = _DecryptionKey;
            tripleDes.IV = new byte[8];

            MemoryStream mStreamEnc = new MemoryStream();
            CryptoStream cryptoStream = new CryptoStream(mStreamEnc, tripleDes.CreateEncryptor(), CryptoStreamMode.Write);

            cryptoStream.Write(uePassword, 0, uePassword.Length);
            cryptoStream.FlushFinalBlock();
            RetVal = mStreamEnc.ToArray();
            cryptoStream.Close();

            return Convert.ToBase64String(RetVal, 0, RetVal.GetLength(0));

        }
        /// <summary>
        /// This Function is used to Decrypt the password        ///
        /// </summary>
        /// <param name="strPWD">String Type parameter that holds the User Password in Encrypted Form</param>
        /// <returns>String Type Parameter that hold the password in Plain Text</returns>
        public static string DecryptPassword(string strPWD)
        {
            byte[] _DecryptionKey = GenerateKey();

            byte[] StoredPassword = Convert.FromBase64String(strPWD);

            System.Text.UnicodeEncoding ue = new System.Text.UnicodeEncoding();
            string RetVal = null;

            TripleDESCryptoServiceProvider tripleDes = new TripleDESCryptoServiceProvider();

            tripleDes.Key = _DecryptionKey;
            tripleDes.IV = new byte[8];

            CryptoStream cryptoStream = new CryptoStream(new MemoryStream(StoredPassword), tripleDes.CreateDecryptor(), CryptoStreamMode.Read);
            MemoryStream msPasswordDec = new MemoryStream();
            int BytesRead = 0;

            byte[] Buffer = new byte[32];
            while ((BytesRead = cryptoStream.Read(Buffer, 0, 32)) > 0)
            {
                msPasswordDec.Write(Buffer, 0, BytesRead);
            }
            cryptoStream.Close();

            RetVal = ue.GetString(msPasswordDec.ToArray());
            msPasswordDec.Close();

            return RetVal;
        }
        #endregion
    }
}